package com.brillilab.service.core.comments.impl;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.brillilab.common.entity.PageVo;
import com.brillilab.dao.mapper.comments.ChatMessageMapper;
import com.brillilab.domain.enums.comments.CommentsClassifyEnum;
import com.brillilab.domain.enums.comments.CommentsContentTypeEnum;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.po.comments.ChatMessage;
import com.brillilab.domain.vo.comments.ChatClassifySearchVo;
import com.brillilab.domain.vo.comments.ChatContentSearchVo;
import com.brillilab.domain.vo.comments.ChatMessageFileVo;
import com.brillilab.domain.vo.comments.ChatFileSearchVo;
import com.brillilab.domain.vo.comments.ChatSearchClassifyVo;
import com.brillilab.domain.vo.comments.ChatSearchFileVo;
import com.brillilab.service.core.comments.IChatMessageService;
import com.github.pagehelper.PageHelper;

import cn.hutool.core.collection.CollUtil;

@Service
@Transactional
public class ChatMessageServiceImpl extends ServiceImpl<ChatMessageMapper, ChatMessage> implements IChatMessageService {

	@Resource
	private ChatMessageMapper chatMessageMapper;

	@Override
	public ChatMessage getNewestOneMessage(Long meMemberId, Long otherMemberId) {
		return chatMessageMapper.getNewestOneMessage(meMemberId, otherMemberId);
	}

	@Override
	public List<ChatMessage> historyMessage(Long meMemberId, Long otherMemberId, Long startMessageId) {
		return chatMessageMapper.historyMessage(meMemberId, otherMemberId, startMessageId);
	}

	@Override
	public List<ChatMessage> newestMessage(Long meMemberId, Long otherMemberId, Long startMessageId) {
		return chatMessageMapper.newestMessage(meMemberId, otherMemberId, startMessageId);
	}

	@Override
	public void setAllMessageRead(Long meMemberId, Long otherMemberId) {
		Assert.isTrue(meMemberId != null && otherMemberId != null, "参数错误");
		LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<ChatMessage>();
		wrapper.eq(ChatMessage::getToMemberId, meMemberId);
		wrapper.eq(ChatMessage::getFromMemberId, otherMemberId);
		wrapper.eq(ChatMessage::getIsRead, BoolEnum.FALSE.getValue());

		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setIsRead(BoolEnum.TRUE.getValue());
		chatMessageMapper.update(chatMessage, wrapper);
	}

	@Override
	public void setMessageRead(Long toMemberId, Integer classify, Long classifyId) {
		Assert.isTrue(toMemberId != null && classify != null && classifyId != null, "参数错误");
		LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<ChatMessage>();
		wrapper.eq(ChatMessage::getToMemberId, toMemberId);
		wrapper.eq(ChatMessage::getClassify, classify);
		wrapper.eq(ChatMessage::getClassifyId, classifyId);
		wrapper.eq(ChatMessage::getIsRead, BoolEnum.FALSE.getValue());

		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setIsRead(BoolEnum.TRUE.getValue());
		chatMessageMapper.update(chatMessage, wrapper);
	}

	@Override
	public void setCommentsDelete(Long commentId) {
		Assert.isTrue(commentId != null, "参数错误");
		LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<ChatMessage>();
		wrapper.eq(ChatMessage::getCommentId, commentId);
		wrapper.eq(ChatMessage::getIsCommentsDelete, BoolEnum.FALSE.getValue());

		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setIsCommentsDelete(BoolEnum.TRUE.getValue());
		chatMessageMapper.update(chatMessage, wrapper);
	}

	@Override
	public PageVo<ChatMessage> searchContent(ChatContentSearchVo searchVo) {
		Assert.isTrue(searchVo != null && searchVo.getMeMemberId() != null, "参数错误");
		PageHelper.startPage(searchVo.getPageNum(), searchVo.getPageSize());
		List<ChatMessage> list = chatMessageMapper.searchContent(searchVo);
		return new PageVo<ChatMessage>(list);
	}

	@Override
	public List<ChatSearchFileVo> searchPicture(ChatFileSearchVo searchVo) {
		List<ChatSearchFileVo> fileListVo = CollUtil.toList();
		List<ChatMessageFileVo> list = chatMessageMapper.searchPicture(searchVo);
		if (CollUtil.isNotEmpty(list)) {
			Map<String, List<ChatMessageFileVo>> map = list.stream()
					.collect(Collectors.groupingBy(ChatMessageFileVo::getCreateDate));
			for (String createDate : map.keySet()) {
				ChatSearchFileVo listVo = new ChatSearchFileVo();
				listVo.setCreateDate(createDate);
				List<Long> fileIds = map.get(createDate).stream().map(ChatMessageFileVo::getFileId)
						.collect(Collectors.toList());
				listVo.setFileIds(fileIds);
				fileListVo.add(listVo);
			}
		}
		return chatMemberSort(fileListVo);
	}

	private List<ChatSearchFileVo> chatMemberSort(List<ChatSearchFileVo> voList) {
		return CollUtil.sort(voList, new Comparator<ChatSearchFileVo>() {
			@Override
			public int compare(ChatSearchFileVo c1, ChatSearchFileVo c2) {
				return c2.getCreateDate().compareTo(c1.getCreateDate());
			}
		});
	}

	@Override
	public int noReadNum(Long meMemberId, Long otherMemberId) {
		LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<ChatMessage>();
		wrapper.eq(ChatMessage::getToMemberId, meMemberId);
		if (otherMemberId != null)
			wrapper.eq(ChatMessage::getFromMemberId, otherMemberId);
		wrapper.eq(ChatMessage::getIsRead, BoolEnum.FALSE.getValue());
		return chatMessageMapper.selectCount(wrapper);
	}

	@Override
	public PageVo<ChatSearchClassifyVo> searchClassify(ChatClassifySearchVo searchVo) {
		PageHelper.startPage(searchVo.getPageNum(), searchVo.getPageSize());
		List<ChatSearchClassifyVo> list = chatMessageMapper.searchClassify(searchVo);
		return new PageVo<ChatSearchClassifyVo>(list);
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<ChatMessage> getCommentsGuideList(List<Long> fromMemberIds, Long toMemberId) {
		if (CollUtil.isNotEmpty(fromMemberIds)) {
			LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<ChatMessage>();
			wrapper.eq(ChatMessage::getToMemberId, toMemberId);
			wrapper.eq(ChatMessage::getIsRead, BoolEnum.FALSE.getValue());
			wrapper.in(ChatMessage::getFromMemberId, fromMemberIds);
			wrapper.eq(ChatMessage::getClassify, CommentsClassifyEnum.EXPERIMENT.getValue());
			wrapper.eq(ChatMessage::getIsCommentsDelete, BoolEnum.FALSE.getValue());
			wrapper.isNotNull(ChatMessage::getCommentId);
			wrapper.orderByDesc(ChatMessage::getId);
			return chatMessageMapper.selectList(wrapper);
		}
		return CollUtil.toList();
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<ChatMessage> getNoReadCard(List<Long> fromMemberIds, Long toMemberId) {
		if (CollUtil.isNotEmpty(fromMemberIds)) {
			LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<ChatMessage>();
			wrapper.eq(ChatMessage::getToMemberId, toMemberId);
			wrapper.eq(ChatMessage::getIsRead, BoolEnum.FALSE.getValue());
			wrapper.in(ChatMessage::getFromMemberId, fromMemberIds);
			wrapper.eq(ChatMessage::getClassify, CommentsClassifyEnum.EXPERIMENT.getValue());
			wrapper.eq(ChatMessage::getContentType, CommentsContentTypeEnum.CARD.getValue());
			wrapper.orderByDesc(ChatMessage::getId);
			return chatMessageMapper.selectList(wrapper);
		}
		return CollUtil.toList();
	}

}
